package gui.std.games.battleships;

import java.awt.BorderLayout;
import java.awt.Container;
import java.awt.GridLayout;
import java.awt.Image;
import java.awt.Point;

import gui.std.GBackgroundedPanel;
import gui.std.GUserItem;

import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextField;

import util.Constants;

import app.Client;
import app.User;

@SuppressWarnings("serial")
public class GBSGame extends JFrame {
	
	public GBSGame(Client c, User r) {
		client = c;
		remote = r;
		initialize();
	}
	
	private void initialize() {
		setSize(WIDTH, HEIGHT);
		setTitle("BattleShips <"+client.getUser().getNick()+" Vs "+remote.getNick()+">");
		setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
		
		c = getContentPane();
		c.setLayout(new BorderLayout(2, 2));
		
		int tp = GBattlePanel.getTotalPoints();		
		info = new GGameInfo(client.getUser(), remote);
		info.setPoints(client.getUser(), tp);
		info.setPoints(remote, tp);
		
		bps = new JPanel(new GridLayout(1, 2, 12, 1));
		
		localBP = new GBattlePanel(client, client.getUser());
		remoteBP = new GBattlePanel(client, remote);
		remoteBP.setPhase(GBattlePanel.WAITING);
		
		bps.add(localBP);
		bps.add(remoteBP);
		
		status = new JTextField(" Setting ships location ...");
		status.setEditable(false);
		status.setBackground(Constants.DEFAULT_BACKGROUND_ITEM_COLOR);		
		status.setFont(Constants.DEFAULT_FONT);
		
		localBP.setDisplay(status);		
		remoteBP.setDisplay(status);
		
		c.add(info, BorderLayout.NORTH);
		c.add(bps);
		c.add(new JScrollPane(status), BorderLayout.SOUTH);
	}
	
	public void setID(long i) {
		id = i;
		localBP.setId(id);
		remoteBP.setId(id);
		setTitle("BattleShips <"+client.getUser().getNick()+" Vs "+remote.getNick()+"> "+"Id: "+id);
	}
	
	public long getId() {
		return id;
	}
	
	public void setReady() {
		status.setText("Ready!! Waiting for enemy attack ... ");
		remoteBP.setPhase(GBattlePanel.WAITING);
		info.setBlink(remote);
	}
	
	public void attack() {
		status.setText("Select position to attack!! ...");
		remoteBP.setPhase(GBattlePanel.ATTACK);
		info.setBlink(client.getUser());
	}
	
	public void showRequest(Point p) {
		if (!localBP.showRequest(p))
			attack();
		else {
			info.decPoints(client.getUser());
			if (info.getPoints(client.getUser()) <= 0) {
				info.setBlink(null);
				showFinalText(false);
			}
		}
	}
	
	public void showResponse(boolean b) {
		remoteBP.showResponse(b);
		//water got... change turn
		if (!b)
			setReady();
		else {
			info.decPoints(remote);
			if (info.getPoints(remote) <= 0) {
				info.setBlink(null);
				showFinalText(true);
			}
		}
	}
	
	private void showFinalText(boolean b) {
		status.setText(b ? " Winner..." : " U Lose...");		
		new Thread() { 
			public void run() {
				for (int i = 0; i < 40; i++) {
					status.setText("  "+status.getText());
					try {
						sleep(200);
					} 
					catch (InterruptedException e) {e.printStackTrace();}
				}
			}
		}.start();
		
		c.remove(bps);
		bps.remove(localBP);
		bps.setBackground(BattleBox.BACKGROUND);

		remoteBP.hold();
		
		Image localImg = new ImageIcon(client.getUser().getPathImage().replace("min", "max")).getImage();
		Image remoteImg = new ImageIcon(remote.getPathImage().replace("min", "max")).getImage();
		
		GBackgroundedPanel backP = new GBackgroundedPanel(b ? localImg : remoteImg);
		backP.setLayout(new BorderLayout());
		backP.setBackground(BattleBox.BACKGROUND);
		
		JLabel l = new JLabel(b ? " Winner..." : " U Lose... ", JLabel.CENTER);
		l.setFont(Constants.DEFAULT_SUPER_MAX_FONT);
		
		backP.add(l, BorderLayout.NORTH);
		
		bps.add(backP);
		c.add(bps);
		bps.updateUI();
	}
	
	private static final int WIDTH = 784;
	private static final int HEIGHT = 480;
	
	private Client client;
	private User remote;
	private long id;
	
	private Container c;
	private JPanel bps;
	private JTextField status;
	
	private GGameInfo info;
	
	private GBattlePanel localBP;
	private GBattlePanel remoteBP;
}

@SuppressWarnings("serial")
class GGameInfo extends JPanel {
	
	public GGameInfo(User l, User r) {
		local = l;
		remote = r;
		initialize();
	}
	
	private void initialize() {
		setLayout(new BorderLayout());
		setBackground(Constants.DEFAULT_BACKGROUND_ITEM_COLOR);

		uA = new GGameInfoBox(local, GGameInfoBox.RIGHT);
		uB = new GGameInfoBox(remote, GGameInfoBox.LEFT);
		time = new JLabel("0:00", JLabel.CENTER);
		time.setFont(Constants.DEFAULT_BIG_MAX_FONT);
		
		add(uA, BorderLayout.WEST);
		add(time);
		add(uB, BorderLayout.EAST);
	}
	
	public void setBlink(User u) {
		if (u != null) {
			uA.setBlink(u.equals(local));
			uB.setBlink(u.equals(remote));
		}
		else {
			uA.setBlink(false);
			uB.setBlink(false);
		}
	}
	
	public void setPoints(User u, int p) {
		GGameInfoBox gi = (uA.getUser().equals(u)) ? uA : uB;
		gi.setPoints(p);
	}
	
	public int getPoints(User u) {
		return (uA.getUser().equals(u)) ? uA.getPoints() : uB.getPoints();
	}
	
	public void incPoints(User u) {
		if (uA.getUser().equals(u)) 
			uA.incPoints();
		else
			uB.incPoints();
	}
	
	public void decPoints(User u) {
		if (uA.getUser().equals(u)) 
			uA.decPoints();
		else
			uB.decPoints();
	}
	
	private User local;
	private User remote;
	
	private GGameInfoBox uA;
	private GGameInfoBox uB;
	private JLabel time;
}

@SuppressWarnings("serial")
class GGameInfoBox extends JPanel {
	
	public GGameInfoBox(User u, String p) {
		user = u;
		pos = p;
		initialize();
	}
	
	private void initialize() {
		setLayout(new BorderLayout());
		setBackground(Constants.DEFAULT_BACKGROUND_ITEM_COLOR);
		
		String aux = (pos == LEFT) ? "-" : "";
		
		pLabel = new JLabel(String.format("%"+aux+"4s", ""+points));
		pLabel.setFont(Constants.DEFAULT_MAX_FONT);
		
		add(ui = new GUserItem(user));
		add(pLabel, pos);
	}
	
	public void setBlink(boolean b) {
		ui.setBlink(b);
	}
	
	public void setPoints(int p) {
		String aux = (pos == LEFT) ? "-" : "";
		pLabel.setText(String.format("%"+aux+"4s", ""+(points = p)));
	}
	
	public int getPoints() {
		return points;
	}
	
	public void incPoints() {
		String aux = (pos == LEFT) ? "-" : "";
		pLabel.setText(String.format("%"+aux+"4s", ""+(++points)));
	}
	
	public void decPoints() {
		String aux = (pos == LEFT) ? "-" : "";
		pLabel.setText(String.format("%"+aux+"4s", ""+(--points)));		
	}
	
	public User getUser() {
		return user;
	}
	
	public static final String LEFT = BorderLayout.WEST;
	public static final String RIGHT = BorderLayout.EAST;
	
	private User user;
	private GUserItem ui;
	private int points;
	private JLabel pLabel;
	private String pos;
}
